package com.infore.siteManagement.service.equipment.impl;

import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.infore.siteManagement.constant.Constants;
import com.infore.siteManagement.constant.ResultConstants;
import com.infore.siteManagement.entity.SiteBasicFile;
import com.infore.siteManagement.entity.equipment.EquipmentModel;
import com.infore.siteManagement.enums.ResultStatus;
import com.infore.siteManagement.repository.equipment.IEquipAndReagentRepository;
import com.infore.siteManagement.repository.equipment.IEquipModelRepository;
import com.infore.siteManagement.repository.equipment.IEquipSolutionRepository;
import com.infore.siteManagement.repository.equipment.IEquipSparePartRepository;
import com.infore.siteManagement.select.QueryDispatcher;
import com.infore.siteManagement.select.dto.QueryParamDto;
import com.infore.siteManagement.select.util.QueryUtil;
import com.infore.siteManagement.service.IFileService;
import com.infore.siteManagement.service.equipment.IEquipModelService;
import com.infore.siteManagement.util.ArrayUtils;
import com.infore.siteManagement.util.FileUtil;
import com.infore.siteManagement.util.MyBeanUtils;
import com.infore.siteManagement.util.ObjectMapperUtil;
import com.infore.siteManagement.util.Page;
import com.infore.siteManagement.util.PageUtil;
import com.infore.siteManagement.util.ResultEntity;

@Service
public class EquipModelServiceImpl implements IEquipModelService {

	@Autowired
	private ObjectMapperUtil objectMapperUtil;
	@Autowired
	private QueryDispatcher queryDispatcher;
	@Autowired
	private IEquipModelRepository iEquipModelRepository;
	@Autowired
	private IEquipSolutionRepository iEquipSolutionRepository;
	@Autowired
	private IEquipSparePartRepository iEquipSparePartRepository;
	@Autowired
	private IEquipAndReagentRepository iEquipAndReagentRepository;
	@Autowired
	private IFileService iFileService;

	public ResultEntity query(QueryParamDto queryParamDto) {
		if (org.springframework.util.StringUtils.isEmpty(queryParamDto)) {// 无任何条件查询
			List<EquipmentModel> list = iEquipModelRepository.findAll();
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
			// 仅分页查询
		} else if (!org.springframework.util.StringUtils.isEmpty(queryParamDto.getPageObject())
				&& org.springframework.util.StringUtils.isEmpty(queryParamDto.getQueryCondition())
				&& org.springframework.util.StringUtils.isEmpty(queryParamDto.getAssembleCondition())
				&& org.springframework.util.StringUtils.isEmpty(queryParamDto.getAssembleSql())) {
			org.springframework.data.domain.Page<EquipmentModel> pageable = iEquipModelRepository
					.findAll(queryParamDto.getPageObject().getPageRequest());
			Page<EquipmentModel> page = PageUtil.pageConvert(pageable);
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
			// 只传属性不传字段的查询
		} else if (org.apache.commons.lang.StringUtils.isBlank(queryParamDto.getAssembleSql().getSelect())) {
			return this.queryAll(queryParamDto);
		}
		// 指定字段查询
		return queryDispatcher.dispatcher(queryParamDto, EquipmentModel.class);
	}

	@SuppressWarnings("serial")
	public ResultEntity queryAll(QueryParamDto queryParamDto) {
		// 判断是否有条件再判断是否需要分页,不分页必须传null
		if (!org.springframework.util.StringUtils.isEmpty(queryParamDto.getPageObject())) {
			// 需要分页
			org.springframework.data.domain.Page<EquipmentModel> pageAble = iEquipModelRepository
					.findAll(new Specification<EquipmentModel>() {
						public Predicate toPredicate(Root<EquipmentModel> root, CriteriaQuery<?> query,
								CriteriaBuilder criteriaBuilder) {
							// 构建条件
							List<Predicate> predicates = com.infore.siteManagement.select.util.QueryUtil
									.createQueryCondition(queryParamDto, criteriaBuilder, root);
							// 组装条件
							Predicate predicate = com.infore.siteManagement.select.util.QueryUtil
									.assembleCondition(queryParamDto, criteriaBuilder, predicates);
							QueryUtil.assembleSql(queryParamDto, criteriaBuilder, query, root, predicate);
							return query.getRestriction();
						}
					}, queryParamDto.getPageObject().getPageRequest());
			Page<EquipmentModel> page = PageUtil.pageConvert(pageAble);
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
		} else {
			List<EquipmentModel> list = iEquipModelRepository.findAll(new Specification<EquipmentModel>() {
				public Predicate toPredicate(Root<EquipmentModel> root, CriteriaQuery<?> query,
						CriteriaBuilder criteriaBuilder) {
					// 构建条件
					List<Predicate> predicates = com.infore.siteManagement.select.util.QueryUtil
							.createQueryCondition(queryParamDto, criteriaBuilder, root);
					// 组装条件
					Predicate predicate = com.infore.siteManagement.select.util.QueryUtil
							.assembleCondition(queryParamDto, criteriaBuilder, predicates);
					QueryUtil.assembleSql(queryParamDto, criteriaBuilder, query, root, predicate);
					return query.getRestriction();
				}
			});
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
		}
	}

	public ResultEntity delete(String id) {
		List<String> ids = ArrayUtils.stringToList(id);
		List<EquipmentModel> equipmentModels = iEquipModelRepository.findByIdIn(ids);
		try {
			for (EquipmentModel equipmentModel : equipmentModels) {
				// 删除仪器模板相关文件
				Set<SiteBasicFile> image = equipmentModel.getImages();
				Set<SiteBasicFile> accessory = equipmentModel.getAccessory();
				if (image != null && image.size() > 0) {
					image.forEach(f -> {
						String path = f.getFilePath();
						File file = new File(FileUtil.BASE_PATH + path);
						file.delete();
					});
				}
				if (accessory != null && accessory.size() > 0) {
					accessory.forEach(f -> {
						String path = f.getFilePath();
						File file = new File(FileUtil.BASE_PATH + path);
						file.delete();
					});
				}
				// 删除仪器
				iEquipModelRepository.delete(equipmentModel);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new ResultEntity(ResultStatus.SUCCESS, Constants.DELETE_FAILUE);
		}
		return new ResultEntity(ResultStatus.SUCCESS, Constants.DELETE_SUCCESS);
	}

	public ResultEntity edit(EquipmentModel equipmentModel, MultipartFile[] imageFiles,
			MultipartFile[] accessoryFiles) {
		String id = equipmentModel.getId();
		Set<SiteBasicFile> image = new HashSet<SiteBasicFile>();
		Set<SiteBasicFile> accessory = new HashSet<SiteBasicFile>();
		try {
			if (StringUtils.isNotBlank(id)) {
				EquipmentModel equipmentModelOld = iEquipModelRepository.findById(id).orElse(null);
				if (equipmentModelOld == null) {
					return new ResultEntity(ResultStatus.SUCCESS, ResultConstants.NO_SUCH_OBJECT);
				}
				// 得到旧的文件,放入到集合中
				Set<SiteBasicFile> imageOld = equipmentModelOld.getImages();
				image.addAll(imageOld);
				Set<SiteBasicFile> accessoryOld = equipmentModelOld.getAccessory();
				accessory.addAll(accessoryOld);
				// 删除仪器模板下的子类
				List<String> equipIds = ArrayUtils.stringToList(id);
				iEquipAndReagentRepository.nativedelByIdIn(equipIds);
				iEquipSolutionRepository.nativedelByIdIn(equipIds);
				iEquipSparePartRepository.nativedelByIdIn(equipIds);
				// 复制空字段
				MyBeanUtils.copyNonNullProperties(equipmentModel, equipmentModelOld);
				equipmentModel = equipmentModelOld;
			}
			// 处理文件
			ResultEntity imageResultEntity = iFileService.uploadSingle(FileUtil.EQUIP_MODEL_IMAGE_FILE, imageFiles);
			ResultEntity accessResultEntity = iFileService.uploadSingle(FileUtil.EQUIP_MODEL_ACCESS__FILE,
					accessoryFiles);
			List<SiteBasicFile> imageList = objectMapperUtil.convertList(imageResultEntity, SiteBasicFile.class);
			List<SiteBasicFile> accessList = objectMapperUtil.convertList(accessResultEntity, SiteBasicFile.class);
			image.addAll(imageList);
			accessory.addAll(accessList);
			image.remove(null);
			accessory.remove(null);
			equipmentModel.setAccessory(accessory);
			equipmentModel.setImages(image);
			iEquipModelRepository.save(equipmentModel);
		} catch (Exception e) {
			e.printStackTrace();
			return new ResultEntity(ResultStatus.SUCCESS, Constants.DEAL_FAILUE);
		}
		if (StringUtils.isNotBlank(id)) {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.UPDATE_SUCCESS);
		} else {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.INSERT_SUCCESS);
		}
	}

}
